gdk_content_formats_unref
gdk_content_formats_print
gdk_content_formats_to_string
+gdk_content_formats_get_mime_types
gdk_content_formats_union
-gdk_content_formats_intersects
-gdk_content_formats_remove
-gdk_content_formats_contains
+gdk_content_formats_match
+gdk_content_formats_contain_mime_type
<SUBSECTION>
GdkContentFormatsBuilder
struct _GdkContentFormats
{
/*< private >*/
- GList *formats;
guint ref_count;
+
+ const char **mime_types; /* interned */
+ gsize n_mime_types;
};
G_DEFINE_BOXED_TYPE (GdkContentFormats, gdk_content_formats,
gdk_content_formats_unref)
-static void
-gdk_content_formats_add_table (GdkContentFormats *formats,
- const char **mime_types,
- guint n_mime_types)
+static GdkContentFormats *
+gdk_content_formats_new_take (const char **mime_types,
+ guint n_mime_types)
{
- gint i;
+ GdkContentFormats *result = g_slice_new0 (GdkContentFormats);
+ result->ref_count = 1;
- for (i = n_mime_types - 1; i >= 0; i--)
- {
- formats->formats = g_list_prepend (formats->formats, (gpointer) gdk_atom_intern (mime_types[i], FALSE));
- }
+ result->mime_types = mime_types;
+ result->n_mime_types = n_mime_types;
+
+ return result;
}
/**
* @nmime_types: number of entries in @mime_types.
*
* Creates a new #GdkContentFormats from an array of mime types.
+ *
+ * The mime types must be different or the behavior of the return value
+ * is undefined. If you cannot guarantee this, use #GdkContentFormatsBuilder
+ * instead.
*
* Returns: (transfer full): the new #GdkContentFormats.
**/
gdk_content_formats_new (const char **mime_types,
guint n_mime_types)
{
- GdkContentFormats *result = g_slice_new (GdkContentFormats);
- result->formats = NULL;
- result->ref_count = 1;
+ GPtrArray *array;
+ guint i;
- if (mime_types)
- gdk_content_formats_add_table (result, mime_types, n_mime_types);
-
- return result;
+ if (n_mime_types == 0)
+ return gdk_content_formats_new_take (NULL, 0);
+
+ array = g_ptr_array_new ();
+ for (i = 0; i < n_mime_types; i++)
+ g_ptr_array_add (array, (gpointer) g_intern_string (mime_types[i]));
+ g_ptr_array_add (array, NULL);
+
+ return gdk_content_formats_new_take ((const char **) g_ptr_array_free (array, FALSE), n_mime_types);
}
/**
if (formats->ref_count > 0)
return;
- g_list_free (formats->formats);
+ g_free (formats->mime_types);
g_slice_free (GdkContentFormats, formats);
}
gdk_content_formats_print (GdkContentFormats *formats,
GString *string)
{
- GList *l;
+ gsize i;
g_return_if_fail (formats != NULL);
g_return_if_fail (string != NULL);
g_string_append (string, "{ ");
- for (l = formats->formats; l; l = l->next)
+ for (i = 0; i < formats->n_mime_types; i++)
{
- if (l != formats->formats)
+ if (i > 0)
g_string_append (string, ", ");
- g_string_append (string, l->data);
+ g_string_append (string, formats->mime_types[i]);
}
g_string_append (string, " }");
}
return gdk_content_formats_builder_free (builder);
}
+static gboolean
+gdk_content_formats_contain_interned_mime_type (const GdkContentFormats *formats,
+ const char *mime_type)
+{
+ gsize i;
+
+ for (i = 0; i < formats->n_mime_types; i++)
+ {
+ if (mime_type == formats->mime_types[i])
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
/**
- * gdk_content_formats_intersects:
+ * gdk_content_formats_match:
* @first: the primary #GdkContentFormats to intersect
* @second: the #GdkContentFormats to intersect with
*
* Returns: The first matching #GdkAtom or %NULL if the formatss
* do not intersect.
*/
-GdkAtom
-gdk_content_formats_intersects (const GdkContentFormats *first,
- const GdkContentFormats *second)
+const char *
+gdk_content_formats_match (const GdkContentFormats *first,
+ const GdkContentFormats *second)
{
- GList *l;
+ gsize i;
g_return_val_if_fail (first != NULL, NULL);
g_return_val_if_fail (second != NULL, NULL);
- for (l = first->formats; l; l = l->next)
+ for (i = 0; i < first->n_mime_types; i++)
{
- if (g_list_find (second->formats, l->data))
- return l->data;
+ if (gdk_content_formats_contain_interned_mime_type (second, first->mime_types[i]))
+ return first->mime_types[i];
}
return NULL;
}
/**
- * gdk_content_formats_contains:
+ * gdk_content_formats_contain_mime_type:
* @formats: a #GdkContentFormats
* @mime_type: the mime type to search for
*
* Returns: %TRUE if the mime_type was found, otherwise %FALSE
**/
gboolean
-gdk_content_formats_contains (const GdkContentFormats *formats,
- const char *mime_type)
+gdk_content_formats_contain_mime_type (const GdkContentFormats *formats,
+ const char *mime_type)
{
g_return_val_if_fail (formats != NULL, FALSE);
g_return_val_if_fail (mime_type != NULL, FALSE);
- return g_list_find (formats->formats, (gpointer) gdk_atom_intern (mime_type, FALSE)) != NULL;
+ return gdk_content_formats_contain_interned_mime_type (formats,
+ g_intern_string (mime_type));
}
-GdkAtom *
-gdk_content_formats_get_atoms (GdkContentFormats *formats,
- guint *n_atoms)
+/**
+ * gdk_content_formats_get_mime_types:
+ * @formats: a #GdkContentFormats
+ * @n_mime_types: (out) (allow-none): optional pointer to take the
+ * number of mime types contained in the return value
+ *
+ * Gets the mime types included in @formats. Note that @formats may not
+ * contain any mime types, in particular when they are empty. In that
+ * case %NULL will be returned.
+ *
+ * Returns: (transfer none): %NULL-terminated array of interned
+ * strings of mime types included in @formats or %NULL if none.
+ **/
+const char * const *
+gdk_content_formats_get_mime_types (GdkContentFormats *formats,
+ gsize *n_mime_types)
{
- GdkAtom *atoms;
- GList *l;
- guint i, n;
-
- n = g_list_length (formats->formats);
- atoms = g_new (GdkAtom, n);
-
- i = 0;
- for (l = formats->formats; l; l = l->next)
- atoms[i++] = l->data;
-
- if (n_atoms)
- *n_atoms = n;
+ g_return_val_if_fail (formats != NULL, NULL);
- return atoms;
+ if (n_mime_types)
+ *n_mime_types = formats->n_mime_types;
+
+ return formats->mime_types;
}
/**
for (l = builder->mime_types; l; l = l->next)
mime_types[i--] = l->data;
- result = gdk_content_formats_new (mime_types, builder->n_mime_types);
- g_free (mime_types);
+ result = gdk_content_formats_new_take (mime_types, builder->n_mime_types);
+
+ g_slist_free (builder->mime_types);
+ g_slice_free (GdkContentFormatsBuilder, builder);
return result;
}
gdk_content_formats_builder_add_formats (GdkContentFormatsBuilder *builder,
const GdkContentFormats *formats)
{
- GList *l;
+ gsize i;
g_return_if_fail (builder != NULL);
g_return_if_fail (formats != NULL);
- for (l = formats->formats; l; l = l->next)
- gdk_content_formats_builder_add_mime_type (builder, l->data);
+ for (i = 0; i < formats->n_mime_types; i++)
+ gdk_content_formats_builder_add_mime_type (builder, formats->mime_types[i]);
}
/**
GDK_AVAILABLE_IN_3_94
char * gdk_content_formats_to_string (GdkContentFormats *formats);
+GDK_AVAILABLE_IN_3_94
+const char * const * gdk_content_formats_get_mime_types (GdkContentFormats *formats,
+ gsize *n_mime_types);
+
GDK_AVAILABLE_IN_3_94
GdkContentFormats * gdk_content_formats_union (GdkContentFormats *first,
const GdkContentFormats *second) G_GNUC_WARN_UNUSED_RESULT;
GDK_AVAILABLE_IN_3_94
-GdkAtom gdk_content_formats_intersects (const GdkContentFormats *first,
+const char * gdk_content_formats_match (const GdkContentFormats *first,
const GdkContentFormats *second);
GDK_AVAILABLE_IN_3_94
-gboolean gdk_content_formats_contains (const GdkContentFormats *formats,
+gboolean gdk_content_formats_contain_mime_type (const GdkContentFormats *formats,
const char *mime_type);
typedef struct _GdkContentFormatsBuilder GdkContentFormatsBuilder;
G_BEGIN_DECLS
-GdkAtom * gdk_content_formats_get_atoms (GdkContentFormats *formats,
- guint *n_atoms);
G_END_DECLS
#include "gdkinternals.h"
#include "gdkproperty.h"
#include "gdkprivate-wayland.h"
-#include "gdkcontentformatsprivate.h"
+#include "gdkcontentformats.h"
#include "gdkdisplay-wayland.h"
#include "gdkseat-wayland.h"
if (accepted)
{
- GdkAtom *atoms;
- guint i, n_atoms;
+ const char *const *mimetypes;
+ gsize i, n_mimetypes;
- atoms = gdk_content_formats_get_atoms (context->formats, &n_atoms);
- for (i = 0; i < n_atoms; i++)
+ mimetypes = gdk_content_formats_get_mime_types (context->formats, &n_mimetypes);
+ for (i = 0; i < n_mimetypes; i++)
{
- if (atoms[i] != gdk_atom_intern_static_string ("DELETE"))
+ if (mimetypes[i] != gdk_atom_intern_static_string ("DELETE"))
break;
}
- if (i < n_atoms)
+ if (i < n_mimetypes)
{
- gchar *mimetype = gdk_atom_name (atoms[i]);
-
- wl_data_offer_accept (wl_offer, context_wayland->serial, mimetype);
- g_free (atoms);
+ wl_data_offer_accept (wl_offer, context_wayland->serial, mimetypes[i]);
return;
}
-
- g_free (atoms);
}
wl_data_offer_accept (wl_offer, context_wayland->serial, NULL);
{
GdkWaylandDragContext *context_wayland;
GdkDragContext *context;
- GdkAtom *atoms;
- guint i, n_atoms;
+ const char *const *mimetypes;
+ gsize i, n_mimetypes;
context_wayland = g_object_new (GDK_TYPE_WAYLAND_DRAG_CONTEXT, NULL);
context = GDK_DRAG_CONTEXT (context_wayland);
context_wayland->dnd_window = create_dnd_window (gdk_window_get_display (window));
context_wayland->dnd_surface = gdk_wayland_window_get_wl_surface (context_wayland->dnd_window);
context_wayland->data_source =
- gdk_wayland_selection_get_data_source (window,
- gdk_wayland_drag_context_get_selection (context));
+ gdk_wayland_selection_get_data_source (window,
+ gdk_wayland_drag_context_get_selection (context));
- atoms = gdk_content_formats_get_atoms (context->formats, &n_atoms);
- for (i = 0; i < n_atoms; i++)
+ mimetypes = gdk_content_formats_get_mime_types (context->formats, &n_mimetypes);
+ for (i = 0; i < n_mimetypes; i++)
{
- gchar *mimetype = gdk_atom_name (atoms[i]);
-
- wl_data_source_offer (context_wayland->data_source, mimetype);
- g_free (mimetype);
+ wl_data_source_offer (context_wayland->data_source, mimetypes[i]);
}
- g_free (atoms);
return context;
}
info = g_hash_table_lookup (selection->offers, wl_data_offer);
- if (!info || gdk_content_formats_contains (info->targets, type))
+ if (!info || gdk_content_formats_contain_mime_type (info->targets, type))
return;
GDK_NOTE (EVENTS,
info = g_hash_table_lookup (selection->offers, gtk_offer);
- if (!info || gdk_content_formats_contains (info->targets, type))
+ if (!info || gdk_content_formats_contain_mime_type (info->targets, type))
return;
GDK_NOTE (EVENTS,
if (target != gdk_atom_intern_static_string ("TARGETS"))
{
- if (!gdk_content_formats_contains (formats, GDK_ATOM_TO_POINTER (target)))
+ if (!gdk_content_formats_contain_mime_type (formats, GDK_ATOM_TO_POINTER (target)))
{
emit_empty_selection_notify (requestor, selection, target);
return;
{
GInputStream *stream = NULL;
int pipe_fd[2];
- guint natoms = 0;
- GdkAtom *targets = NULL;
+ gsize n_targets = 0;
+ const char * const *targets = NULL;
if (target == gdk_atom_intern_static_string ("TARGETS"))
{
- targets = gdk_content_formats_get_atoms (formats, &natoms);
+ targets = gdk_content_formats_get_mime_types (formats, &n_targets);
}
else
{
if (targets)
{
/* Store directly the local atoms */
- selection_buffer_append_data (buffer_data, targets, natoms * sizeof (GdkAtom));
- g_free (targets);
+ selection_buffer_append_data (buffer_data, targets, n_targets * sizeof (const char * const *));
}
g_hash_table_insert (selection_data->buffers,
{
if (context->formats)
{
- GdkAtom *atoms;
- guint n_atoms;
+ const char * const *atoms;
+ gsize n_atoms;
- atoms = gdk_content_formats_get_atoms (context->formats, &n_atoms);
+ atoms = gdk_content_formats_get_mime_types (context->formats, &n_atoms);
_gdk_x11_precache_atoms (GDK_WINDOW_DISPLAY (context->source_window),
(const gchar **) atoms,
n_atoms);
-
- g_free (atoms);
}
}
{
GdkDragContext *context = GDK_DRAG_CONTEXT (context_x11);
Atom *atomlist;
- GdkAtom *atoms;
- guint i, n_atoms;
+ const char * const *atoms;
+ gsize i, n_atoms;
GdkDisplay *display = GDK_WINDOW_DISPLAY (context->source_window);
- atoms = gdk_content_formats_get_atoms (context->formats, &n_atoms);
+ atoms = gdk_content_formats_get_mime_types (context->formats, &n_atoms);
atomlist = g_new (Atom, n_atoms);
for (i = 0; i < n_atoms; i++)
- atomlist[i] = gdk_x11_atom_to_xatom_for_display (display, atoms[i]);
+ atomlist[i] = gdk_x11_get_xatom_by_name_for_display (display, atoms[i]);
XChangeProperty (GDK_WINDOW_XDISPLAY (context->source_window),
GDK_WINDOW_XID (context->source_window),
(guchar *)atomlist, n_atoms);
g_free (atomlist);
- g_free (atoms);
context_x11->xdnd_targets_set = 1;
}
{
GdkDragContext *context = GDK_DRAG_CONTEXT (context_x11);
GdkDisplay *display = GDK_WINDOW_DISPLAY (context->dest_window);
- GdkAtom *atoms;
- guint i, n_atoms;
+ const char * const *atoms;
+ gsize i, n_atoms;
XEvent xev;
xev.xclient.type = ClientMessage;
GDK_NOTE(DND,
g_message ("Sending enter source window %#lx XDND protocol version %d\n",
GDK_WINDOW_XID (context->source_window), context_x11->version));
- atoms = gdk_content_formats_get_atoms (context->formats, &n_atoms);
+ atoms = gdk_content_formats_get_mime_types (context->formats, &n_atoms);
if (n_atoms > 3)
{
/* GTK+ traditionally has used application/x-rootwin-drop,
* but the XDND spec specifies x-rootwindow-drop.
*/
- if (gdk_content_formats_contains (context->formats, "application/x-rootwindow-drop") ||
- gdk_content_formats_contains (context->formats, "application/x-rootwin-drop"))
+ if (gdk_content_formats_contain_mime_type (context->formats, "application/x-rootwindow-drop") ||
+ gdk_content_formats_contain_mime_type (context->formats, "application/x-rootwin-drop"))
context->action = context->suggested_action;
else
context->action = 0;
GdkContentFormats *formats)
{
GtkWidget *clipboard_widget;
- guint n_atoms;
if (clipboard->selection != GDK_SELECTION_CLIPBOARD)
return;
if (formats)
{
- clipboard->storable_formats = gdk_content_formats_get_atoms (formats, &n_atoms);
- clipboard->n_storable_formats = n_atoms;
+ const char * const *mime_types;
+ gsize n_mime_types;
+
+ mime_types = gdk_content_formats_get_mime_types (formats, &n_mime_types);
+ clipboard->storable_formats = g_memdup (mime_types, sizeof (char *) * n_mime_types);
+ clipboard->n_storable_formats = n_mime_types;
}
else
{
if (site && site->target_list)
{
- if (gdk_content_formats_contains (site->target_list, target))
+ if (gdk_content_formats_contain_mime_type (site->target_list, target))
{
if (!(site->flags & GTK_DEST_DEFAULT_DROP) ||
gtk_selection_data_get_length (selection_data) >= 0)
/* GTK+ traditionally has used application/x-rootwin-drop, but the
* XDND spec specifies x-rootwindow-drop.
*/
- if (gdk_content_formats_contains (info->target_list, "application/x-rootwindow-drop"))
+ if (gdk_content_formats_contain_mime_type (info->target_list, "application/x-rootwindow-drop"))
found = gdk_atom_intern ("application/x-rootwindow-drop", FALSE);
- if (gdk_content_formats_contains (info->target_list, "application/x-rootwin-drop"))
+ if (gdk_content_formats_contain_mime_type (info->target_list, "application/x-rootwin-drop"))
found = gdk_atom_intern ("application/x-rootwin-drop", FALSE);
else found = NULL;
info->context);
gtk_selection_data_set (selection_data, null_atom, 8, NULL, 0);
}
- else if (gdk_content_formats_contains (info->target_list,
- gtk_selection_data_get_target (selection_data)))
+ else if (gdk_content_formats_contain_mime_type (info->target_list,
+ gtk_selection_data_get_target (selection_data)))
{
g_signal_emit_by_name (info->widget, "drag-data-get",
info->context,
if (target_list == NULL)
return NULL;
- result = gdk_content_formats_intersects (target_list,
- gdk_drag_context_get_formats (context));
+ result = gdk_content_formats_match (target_list,
+ gdk_drag_context_get_formats (context));
return result;
}
GdkAtom selection,
GdkContentFormats *targets)
{
- GdkAtom *atoms;
- guint n_targets;
+ const char * const *mime_types;
+ gsize n_mime_types;
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (selection != NULL);
gtk_selection_target_list_add (widget, selection, targets);
- atoms = gdk_content_formats_get_atoms (targets, &n_targets);
- gdk_selection_add_targets (gtk_widget_get_window (widget), selection, atoms, n_targets);
- g_free (atoms);
+ mime_types = gdk_content_formats_get_mime_types (targets, &n_mime_types);
+ gdk_selection_add_targets (gtk_widget_get_window (widget), selection, (GdkAtom *) mime_types, n_mime_types);
}
list = gtk_content_formats_add_image_targets (list, writable);
for (i = 0; i < n_targets && !result; i++)
{
- if (gdk_content_formats_contains (list, targets[i]))
+ if (gdk_content_formats_contain_mime_type (list, targets[i]))
{
result = TRUE;
break;
target_list = gtk_selection_target_list_get (widget, data->selection);
if (data->target != gtk_selection_atoms[SAVE_TARGETS] &&
target_list &&
- gdk_content_formats_contains (target_list, data->target))
+ gdk_content_formats_contain_mime_type (target_list, data->target))
{
g_signal_emit_by_name (widget,
"selection-get",
else if (data->target == gtk_selection_atoms[TARGETS])
{
/* List of all targets supported for this widget/selection pair */
- GdkAtom *p, *atoms;
- guint count, i;
+ GdkAtom *p;
+ const char * const *atoms;
+ gsize count, i;
GdkContentFormats *target_list;
target_list = gtk_selection_target_list_get (widget,
data->selection);
- atoms = gdk_content_formats_get_atoms (target_list, &count);
+ atoms = gdk_content_formats_get_mime_types (target_list, &count);
data->type = GDK_SELECTION_TYPE_ATOM;
data->format = 32;
for (i = 0; i < count; i++)
*p++ = atoms[i];
-
- g_free (atoms);
}
else if (data->target == gtk_selection_atoms[SAVE_TARGETS])
{
buffer_formats = gdk_content_formats_new (atoms, n_atoms);
dnd_formats = gdk_drag_context_get_formats (context);
- target = gdk_content_formats_intersects (dnd_formats, buffer_formats);
+ target = gdk_content_formats_match (dnd_formats, buffer_formats);
gdk_content_formats_unref (buffer_formats);
g_free (atoms);
gtk_image_set_from_pixbuf (GTK_IMAGE (widget), trashcan_closed);
formats = gdk_drag_context_get_formats (context);
- format = gdk_content_formats_intersects (formats, formats);
+ format = gdk_content_formats_match (formats, formats);
if (format)
{
gtk_drag_get_data (widget, context,